package com.drakulo.games.ais.ui.component;

import java.math.BigDecimal;
import java.math.RoundingMode;

import org.newdawn.slick.Color;
import org.newdawn.slick.Font;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.geom.Rectangle;

import com.drakulo.games.ais.core.NumberHelper;
import com.drakulo.games.ais.ui.FontHelper;
import com.drakulo.games.ais.ui.UIHelper;

public class ProgressBar extends UIComponent {
	private static final int NORMAL = 0;
	private static final int HOVERED = 1;
	private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);

	private BigDecimal value;
	private BigDecimal maxValue;
	private Color emptyColor;
	private Color filledColor;
	private int state;
	private String title;
	private boolean displayValues;

	public ProgressBar() {
		this(false);
	}

	public ProgressBar(boolean displayValues) {
		this.value = BigDecimal.ZERO;
		this.maxValue = HUNDRED;
		this.displayValues = displayValues;
	}

	public int getWidth() {
		return this.width;
	}

	public void setWidth(int width) {
		this.width = width;
	}

	public int getHeight() {
		return this.height;
	}

	public void setHeight(int height) {
		this.height = height;
	}

	public BigDecimal getValue() {
		return this.value;
	}

	public void setValue(BigDecimal value) {
		this.value = value;
	}

	public Color getEmptyColor() {
		return this.emptyColor;
	}

	public void setEmptyColor(Color emptyColor) {
		this.emptyColor = emptyColor;
	}

	public Color getFilledColor() {
		return this.filledColor;
	}

	public void setFilledColor(Color filledColor) {
		this.filledColor = filledColor;
	}

	public void setX(int x) {
		this.ox = x;
	}

	public void setY(int y) {
		this.oy = y;
	}

	public BigDecimal getMaxValue() {
		return this.maxValue;
	}

	public void setMaxValue(BigDecimal maxValue) {
		this.maxValue = maxValue;
	}

	@Override
	public void render(Graphics g) throws SlickException {
		UIHelper.drawDarkBox(g, this.ox, this.oy, this.width, this.height);
		Font font = FontHelper.getFont(FontHelper.HEMI_HEAD, this.filledColor, 20);
		if (this.state == HOVERED) {
			// The progressbar is hovered. If there is a title, it is shown in
			// place of the percentage
			if (this.title != null) {
				g.setColor(this.filledColor);
				font.drawString(this.ox + 2, this.oy + 2, this.title);
				return;
			}
		}
		int percentage;
		if (this.maxValue.equals(BigDecimal.ZERO)) {
			// Avoiding division by zero
			percentage = 0;
		} else {
			percentage = this.value.multiply(HUNDRED)
					.divide(this.maxValue, 2, RoundingMode.HALF_UP).intValue();
		}

		final int max = this.width - 1;
		final int w = NumberHelper.ruleOf3(100, max, percentage);
		final int midHeight = this.height / 2;
		for (int i = 0; i < max - 1; i++) {
			if (i % 2 == 1 || i == max) {
				continue;
			}
			if (i < w) {
				g.setColor(this.filledColor);
			} else {
				g.setColor(Color.black);
			}
			int drawX = this.ox + i + 2;
			int height = this.oy + (this.height - 2);
			if (this.displayValues) {
				height = midHeight + this.oy;
			}
			g.drawLine(drawX, this.oy + 2, drawX, height);
		}

		if (this.displayValues) {
			Font sfont = FontHelper.getFont(FontHelper.VISITOR,
					FontHelper.convert(Color.white), midHeight);
			sfont.drawString(this.ox + 2, this.oy + midHeight + 1, this.value
					+ "/" + this.maxValue);
		}

	}

	@Override
	public void update(Input input) throws SlickException {
		// If a hover title is defined, render it if the mouse is on the
		// progress bar
		Rectangle bounds = new Rectangle(this.ox, this.oy, this.width,
				this.height);
		if (bounds.contains(input.getMouseX(), input.getMouseY())) {
			// Hover detected
			this.state = HOVERED;
		} else {
			this.state = NORMAL;
		}
	}

	public String getTitle() {
		return this.title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

}